/**
 * @author Brad Leege <bleege@gmail.com>
 * Created on 3/9/14 at 2:50 PM
 */

package com.forestar.mapControl.utils;

import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;

import com.forestar.mapControl.utils.bitmapcache.CacheableBitmapDrawable;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class BitmapUtils
  {
    private static final String TAG = "BitmapUtils";
    public static final int[] EXPIRED = new int[]{-1};

    public static BitmapFactory.Options getBitmapOptions(DisplayMetrics mDisplayMetrics)
      {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inDensity = DisplayMetrics.DENSITY_DEFAULT;
        options.inTargetDensity = mDisplayMetrics.densityDpi;
        return options;
      }

    public static boolean isCacheDrawableExpired(Drawable drawable)
      {
        if (drawable != null && drawable.getState() == EXPIRED)
          {
            return true;
          }
        return false;
      }

    public static void setCacheDrawableExpired(CacheableBitmapDrawable drawable)
      {
        if (drawable != null)
          {
            drawable.setState(EXPIRED);
          }
      }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private static class ActivityManagerHoneycomb
      {
        static int getLargeMemoryClass(ActivityManager activityManager)
          {
            return activityManager.getLargeMemoryClass();
          }
      }

    public static int calculateMemoryCacheSize(Context context)
      {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        boolean largeHeap = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_LARGE_HEAP) != 0;
        int memoryClass = am.getMemoryClass();
        if (largeHeap && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
          {
            memoryClass = ActivityManagerHoneycomb.getLargeMemoryClass(am);
          }
        Log.d(TAG, "LargeHeap enabled? = '" + largeHeap + "'");
        // Target ~15% of the available heap.
        int heapRes = 1024 * 1024 * memoryClass / 7;
        Log.d(TAG, "Heap Reserve Request For Cache Size = '" + heapRes + "'");
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        am.getMemoryInfo(memoryInfo);
        Log.d(TAG, "Available Memory = '" + memoryInfo.availMem + "'");
        return heapRes;
      }

    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
      {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth)
          {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
              {
                inSampleSize *= 2;
              }
          }
        return inSampleSize;
      }

    // 如果是放大图片，filter决定是否平滑，如果是缩小图片，filter无影响
    private static Bitmap createScaleBitmap(Bitmap src, int dstWidth, int dstHeight)
      {
        Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
        if (src != dst)
          { // 如果没有缩放，那么不回收
            src.recycle(); // 释放Bitmap的native像素数组
          }
        return dst;
      }

    // 从Resources中加载图片
    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight)
      {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options); // 读取图片长款
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 计算inSampleSize
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeResource(res, resId, options); // 载入一个稍大的缩略图
        return createScaleBitmap(src, reqWidth, reqHeight); // 进一步得到目标大小的缩略图
      }

    // 从sd卡上加载图片
    public static Bitmap decodeSampledBitmapFromFd(String pathName, int reqWidth, int reqHeight)
      {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(pathName, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeFile(pathName, options);
        return createScaleBitmap(src, reqWidth, reqHeight);
      }


    //给bitmap添加背景色(比如白色)
    //todo 注意，本方法只适合单图层的处理，如果需要用到多层级（标注图覆盖bitmap时，就会无法显示出下一层影像）
    public static Bitmap drawBg4Bitmap(int color, Bitmap orginBitmap) {
      Paint paint = new Paint();
      paint.setColor(color);
      Bitmap bitmap = Bitmap.createBitmap(orginBitmap.getWidth(),
              orginBitmap.getHeight(), orginBitmap.getConfig());
      Canvas canvas = new Canvas(bitmap);
      canvas.drawRect(0, 0, orginBitmap.getWidth(), orginBitmap.getHeight(), paint);
      canvas.drawBitmap(orginBitmap, 0, 0, paint);
      return bitmap;
    }


    /**
     * 偏移效果
     * @param origin 原图   直接oom了
     * @return 偏移后的bitmap
     */
    private Bitmap skewBitmap(Bitmap origin,float distanceX,float distanceY) {
      if (origin == null) {
        return null;
      }
      int width = origin.getWidth();
      int height = origin.getHeight();
      Matrix matrix = new Matrix();
      matrix.postSkew(distanceX, distanceY);
      Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
      if (newBM.equals(origin)) {
        return newBM;
      }
      origin.recycle();
      return newBM;
    }


    //压缩bitmap  按照质量压缩
    public static Bitmap compressbySample(Bitmap image, Bitmap.CompressFormat compressFormat) {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      image.compress(compressFormat, 60, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
      ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中

      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inPreferredConfig = Bitmap.Config.RGB_565;
      options.inPurgeable = true;
      options.inJustDecodeBounds = true;//只读取图片的头信息，不去解析真是的位图
      BitmapFactory.decodeStream(isBm, null, options);
      options.inSampleSize = 2;
      options.inJustDecodeBounds = false;//真正的解析位图
      isBm.reset();
      Bitmap compressBitmap;
      try {
        compressBitmap = BitmapFactory.decodeStream(isBm, null, options);//把ByteArrayInputStream数据生成图片
      } catch (OutOfMemoryError e) {
        compressBitmap = null;
        System.gc();
      }

      return compressBitmap;
    }

    //本地文件获取图片
//            String fileNameSave = tile.getRelativePath();
//            String fileDirectorySave = buildTempFileDirectory();
//
//            File tileFileSave = new File(fileDirectorySave+fileNameSave);
//            File tileFileSave1 = new File(fileDirectorySave+tileFileSave.getName());
//            List<File> parentFile = new ArrayList<>();
//            File tempParentFile = tileFileSave.getParentFile();
//            while (!tempParentFile.exists()){
//                parentFile.add(tempParentFile);
//                LogD.d("添加文件夹："+tempParentFile.getPath());
//                tempParentFile = tempParentFile.getParentFile();
//            }
//            for (int i = parentFile.size()-1; i>-1; i--) {
//                parentFile.get(i).mkdir();
//                LogD.d("创建文件夹："+parentFile.get(i).getPath());
//            }

//            if (!tileFileSave1.exists() ) {
//                FileOutputStream out = null;
//                try {
//                    out = new FileOutputStream(tileFileSave1);
//                    bitmapDrawable.getBitmap().compress(Bitmap.CompressFormat.PNG, 90, out);
//                    out.flush();
//                    out.close();
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//                Bitmap bitmap = BitmapFactory.decodeFile(tileFile.getAbsolutePath() );
//                if (bitmap != null) {
//                    return MapCachePool2.getInstance().putBitmapFromTask(tile, bitmap);
//                }
//            }
//            return bitmapDrawable;
  }
